package com.hivekion.common.response;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hivekion.common.entity.BusinessExceptionInfo;
import com.hivekion.common.entity.ResponseData;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * 控制器类增强：可以对Controller中所有使用@RequestMapping注解的方法增强
  */
@RestControllerAdvice(basePackages = "com.hivekion")
public class ResponseResult<T> implements ResponseBodyAdvice<Object> {

      /**
       * 这个方法的返回值，决定是否启动结果响应拦截，当返回为true是，表示拦截
       */
      @Override
      public boolean supports(
	      MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
	    return true;
      }

      /**
       * 被拦截的响应，立即执行该方法。 body ：是请求控制器方法接口后，响应的内容。（其他参数不用了解）
       */
      @Override
      public Object beforeBodyWrite(
	      Object body,
	      MethodParameter returnType,
	      MediaType selectedContentType,
	      Class<? extends HttpMessageConverter<?>> selectedConverterType,
	      ServerHttpRequest request,
	      ServerHttpResponse response) {
	    if (returnType.getGenericParameterType().equals(String.class)) { // String类型不能直接包装
		  ObjectMapper objectMapper = new ObjectMapper();
		  try {
			return objectMapper.writeValueAsString(ResponseData.success(body));
		  } catch (JsonProcessingException e) {
			e.printStackTrace(); // 这里正常应该加如自定义的统一异常处理
		  }
	    } else if (body instanceof BusinessExceptionInfo) { // 判断返回值结果是否是一个异常对象类型
		  BusinessExceptionInfo result = (BusinessExceptionInfo) body;
		  return ResponseData.generator(result.getCode(), result.getMessage(), null);
	    }
	    return ResponseData.success(body);
      }
}
